using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using System.Diagnostics;
using CKS.EBE.API;
using CKS.EBE.Linkbacks;

namespace CKS.EBE
{
	public class LinkbackJob : SPJobDefinition
	{
		public LinkbackJob()
			: base()
		{ }

		public LinkbackJob(string jobName, SPService service, SPServer server, SPJobLockType targetType)
			: base(jobName, service, server, targetType)
		{ }

		public LinkbackJob(string jobName, SPWebApplication webApplication)
			: base(jobName, webApplication, null, SPJobLockType.ContentDatabase)
		{
			Title = "Send Trackbacks and Pingbacks";
		}

		public override void Execute(Guid contentDbId)
		{
			try
			{
				// get a reference to the current site collection's content database
				var webApplication = (SPWebApplication)Parent;
				SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];
				var ebeFeature = new Guid("BBE9DEF7-2FE9-A0B1-D7BB-AA128C837EBE");
				// loop through each site and web to look for ebe webs
				foreach (SPSite site in contentDb.Sites)
				{
					try
					{
						foreach (SPWeb web in site.AllWebs)
						{
							try
							{

								if (web.Features[ebeFeature] != null)
								{
									// we have a ebe web. check if we have something to do
									Pingback(web);
								}
							}
							catch (Exception ex)
							{
								Trace.Write("LinkbackJob can not access web: " + ex.Message);
							}
							finally
							{
								web.Dispose();
							}
						}
					}
					catch (Exception ex)
					{
						Trace.Write("LinkbackJob can not access site: " + ex.Message);
					}
					finally
					{
						site.Dispose();
					}
				}
			}
			catch (Exception ex)
			{
				Trace.Write("Error executing the LinkbackJob: " + ex);
			}
		}

		/// <summary>
		/// read itemIds from web.Properties, and deal pingback items which are not published
		/// </summary>
		/// <param name="web"></param>
		private static void Pingback(SPWeb web)
		{
			string property = web.Properties["EBE_PingbackIDs"];
			if (string.IsNullOrEmpty(property)) return;

			var properties = new List<string>(property.Split(';'));
			string postsListName = Localization.GetListName(Localization.BlogList.Posts, web.Language);
			SPList postsList = Helper.GetListByFolderName(web, postsListName);

			foreach (string itemId in properties)
			{
				if (string.IsNullOrEmpty(itemId)) continue;
				try
				{
					web.AllowUnsafeUpdates = true;
					SPListItem item = postsList.GetItemById(int.Parse(itemId));
					var postPublishedDate = (DateTime)item[SPBuiltInFieldId.PublishedDate];
					if (postPublishedDate <= DateTime.Now)
					{
						// the post is now published. so we need to ping it
						var pinger = new LinkbackPinger(web);
						pinger.SendLinkbackPings(item);

						// remove the itemId from the web.Properties
						property = property.Replace(string.Format(";{0}", itemId), "");
						web.Properties["EBE_PingbackIDs"] = property;
						web.Properties.Update();
						web.Update();
					}
				}
				catch (Exception ex)
				{
					Trace.Write(string.Format("Can not ping item with ID {0} in web {1}: {2}", itemId, web.Url, ex));
				}
				finally
				{
					web.AllowUnsafeUpdates = false;
				}
			}
		}

		/// <summary>
		/// Submits the job and schedules it to run on every server in the Farm.
		/// </summary>
		public void SubmitJob()
		{
			// the job will run every hour at 10 minutes past the full hour
			Schedule = new SPHourlySchedule();
			((SPHourlySchedule)Schedule).BeginMinute = 10;
			((SPHourlySchedule)Schedule).EndMinute = 20;

			Title = string.Format("Send Trackbacks and Pingbacks ({0})", WebApplication.Name);
			Update();
		}

		/// <summary>
		/// Check if a job with the name already exists.
		/// </summary>
		/// <returns></returns>
		public bool JobAlreadyExists()
		{
			var jobTitle = string.Format("Send Trackbacks and Pingbacks ({0})", WebApplication.Name);
			foreach (SPJobDefinition jobDefinition in WebApplication.JobDefinitions)
			{
				if (jobDefinition.Title == jobTitle) return true;
			}
			return false;
		}
	}
}